์ ์๋ @package ๊ท์น์ผ๋ก CSS ์ํคํ ์ฒ์ ๋ฏธ๋๋ฅผ ํ์ํด ๋ณด์ธ์. ๋ค์ดํฐ๋ธ CSS ํจํค์ง ๊ด๋ฆฌ, ์บก์ํ, ์ข ์์ฑ ์ฒ๋ฆฌ์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์ด๋์ ๋๋ค.
CSS ํ๋ช : ๋ค์ดํฐ๋ธ ํจํค์ง ๊ด๋ฆฌ๋ฅผ ์ํ @package ๊ท์น ์ฌ์ธต ๋ถ์
์์ญ ๋ ๋์ ๊ฐ๋ฐ์๋ค์ CSS(Cascading Style Sheets)์ ๊ฐ์ฅ ํน์ง์ ์ด๊ณ ์ด๋ ค์ด ๊ธฐ๋ฅ ์ค ํ๋์ธ ์ ์ญ์ ํน์ฑ๊ณผ ์จ๋ฆํด์์ต๋๋ค. ๊ฐ๋ ฅํ๊ธด ํ์ง๋ง, CSS์ ์ ์ญ ์ค์ฝํ๋ ์๋ง์ ๋ช ์์ฑ ์ ์, ๋ค์ด๋ฐ ์ปจ๋ฒค์ ๋ ผ์, ์ํคํ ์ฒ ๊ณจ์นซ๊ฑฐ๋ฆฌ์ ์์ธ์ด์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฅผ ๊ธธ๋ค์ด๊ธฐ ์ํด BEM ๋ฐฉ๋ฒ๋ก ๋ถํฐ ๋ณต์กํ JavaScript ๊ธฐ๋ฐ ์๋ฃจ์ ์ ์ด๋ฅด๊ธฐ๊น์ง CSS ์์ ์ ๊ตํ ์์คํ ์ ๊ตฌ์ถํด์์ต๋๋ค. ํ์ง๋ง ํด๊ฒฐ์ฑ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ปจ๋ฒค์ ์ด ์๋๋ผ CSS ์ธ์ด ์์ฒด์ ๋ค์ดํฐ๋ธ ๊ธฐ๋ฅ์ด๋ผ๋ฉด ์ด๋จ๊น์? ๋ฐ๋ก CSS ํจํค์ง ๊ท์น(CSS Package Rule)์ด๋ผ๋ ๊ฐ๋ ์ด ๋ฑ์ฅํ์ต๋๋ค. ์ด๋ ๊ฐ๋ ฅํ ๋ธ๋ผ์ฐ์ ๋ค์ดํฐ๋ธ ํจํค์ง ๊ด๋ฆฌ๋ฅผ ์ฐ๋ฆฌ ์คํ์ผ์ํธ์ ์ง์ ๋์ ํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ ๋ฏธ๋ ์งํฅ์ ์ธ ์ ์์ ๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋์์๋ ์ด ํ์ ์ ์ธ ์ ์์ ํ๊ตฌํฉ๋๋ค. ์ด ๊ท์น์ด ํด๊ฒฐํ๊ณ ์ ํ๋ ํต์ฌ ๋ฌธ์ ๋ฅผ ๋ถ์ํ๊ณ , ์ ์๋ ๊ตฌ๋ฌธ๊ณผ ๋ฉ์ปค๋์ฆ์ ๋ถ์ํ๋ฉฐ, ์ค์ ๊ตฌํ ์์ ๋ฅผ ์ดํด๋ณด๊ณ , ์ด๊ฒ์ด ์น ๊ฐ๋ฐ์ ๋ฏธ๋์ ์ด๋ค ์๋ฏธ๋ฅผ ๊ฐ๋์ง ์์๋ณผ ๊ฒ์ ๋๋ค. ๋์์ธ ์์คํ ํ์ฅ์ฑ์ ์ด๋ ค์์ ๊ฒช๋ ์ํคํ ํธ์ด๋ , ํด๋์ค ์ด๋ฆ์ ์ ๋์ฌ๋ฅผ ๋ถ์ด๋ ๋ฐ ์ง์น ๊ฐ๋ฐ์์ด๋ , CSS์ ์ด๋ฌํ ์งํ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
ํต์ฌ ๋ฌธ์ : ์ CSS์ ๋ค์ดํฐ๋ธ ํจํค์ง ๊ด๋ฆฌ๊ฐ ํ์ํ๊ฐ
ํด๊ฒฐ์ฑ ์ ์ ๋๋ก ์ดํดํ๊ธฐ ์ ์, ์ฐ๋ฆฌ๋ ๋จผ์ ๋ฌธ์ ๋ฅผ ์์ ํ ์ดํดํด์ผ ํฉ๋๋ค. ๋๊ท๋ชจ๋ก CSS๋ฅผ ๊ด๋ฆฌํ๋ ์ด๋ ค์์ ์๋ก์ด ๊ฒ์ด ์๋์ง๋ง, ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ์ ๊ฑฐ๋ํ๊ณ ํ์ ์ ์ธ ํ๋ก์ ํธ ์๋์ ๋์ฑ ์ฌ๊ฐํด์ก์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ค์ ์ฃผ๋ก ์ธ์ด์ ๋ช ๊ฐ์ง ๊ทผ๋ณธ์ ์ธ ํน์ฑ์์ ๋น๋กฏ๋ฉ๋๋ค.
์ ์ญ ๋ค์์คํ์ด์ค ๋ฌธ์
CSS์์ ์ฌ๋ฌ๋ถ์ด ์์ฑํ๋ ๋ชจ๋ ์ ํ์๋ ๋จ์ผํ๊ณ ๊ณต์ ๋ ์ ์ญ ์ค์ฝํ์ ์กด์ฌํฉ๋๋ค. ํค๋ ์ปดํฌ๋ํธ์ ์คํ์ผ์ํธ์์ ์ ์๋ .button ํด๋์ค๋ ํธํฐ ์ปดํฌ๋ํธ์ ์คํ์ผ์ํธ์์ ์ฐธ์กฐํ๋ .button ํด๋์ค์ ๋์ผํฉ๋๋ค. ์ด๋ ์ฆ์ ์ถฉ๋์ ๋์ ์ํ์ ์ผ๊ธฐํฉ๋๋ค.
๊ฐ๋จํ๊ณ ํํ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ด ์๋ค. ์ฌ๋ฌ๋ถ์ ํ์ด ๋ฉ์ง ์นด๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฐํฉ๋๋ค:
.card { background: white; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
.title { font-size: 1.5em; color: #333; }
๋์ค์ ๋ค๋ฅธ ํ์ด ์๋ํํฐ ๋ธ๋ก๊ทธ ์์ ฏ์ ํตํฉํ๋๋ฐ, ์ด ์์ ฏ ์ญ์ .card์ .title์ด๋ผ๋ ์ผ๋ฐ์ ์ธ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉํ์ง๋ง ์คํ์ผ์ ์์ ํ ๋ค๋ฆ
๋๋ค. ๊ฐ์๊ธฐ ์ฌ๋ฌ๋ถ์ ์นด๋ ์ปดํฌ๋ํธ๊ฐ ๊นจ์ง๊ฑฐ๋ ๋ธ๋ก๊ทธ ์์ ฏ์ด ์ด์ํ๊ฒ ๋ณด์
๋๋ค. ๋ง์ง๋ง์ ๋ก๋๋ ์คํ์ผ์ํธ๊ฐ ์ด๊ธฐ๊ณ , ์ฌ๋ฌ๋ถ์ ์ด์ ๋ช
์์ฑ์ด๋ ์์ค ์์ ๋ฌธ์ ๋ฅผ ๋๋ฒ๊น
ํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ์ ์ญ์ ํน์ฑ์ ๊ฐ๋ฐ์๋ค์ด ๋ฐฉ์ด์ ์ธ ์ฝ๋ฉ ํจํด์ ์ฌ์ฉํ๋๋ก ๊ฐ์ํฉ๋๋ค.
์์กด์ฑ ๊ด๋ฆฌ ์ง์ฅ
ํ๋์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฑฐ์ ์ฒ์๋ถํฐ ๋ง๋ค์ด์ง์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, UI ํคํธ, ํ๋ ์์ํฌ์ ํ๋ถํ ์ํ๊ณ์ ์์กดํฉ๋๋ค. ์ด๋ฌํ ์์กด์ฑ์ ์คํ์ผ์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ข ์ข ๊นจ์ง๊ธฐ ์ฌ์ด ๊ณผ์ ์ ๋๋ค. ๊ฑฐ๋ํ๊ณ ๋จ์ผํ CSS ํ์ผ์ ๊ฐ์ ธ์์ ํ์ํ ๋ถ๋ถ์ ๋ฎ์ด์ฐ๋ฉด์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ง๊ฐ๋จ๋ฆฌ์ง ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋์? ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์๋ค์ด ์ฌ๋ฌ๋ถ์ ์ฝ๋์ ์ถฉ๋์ ํผํ๊ธฐ ์ํด ๋ชจ๋ ํด๋์ค๋ฅผ ์๋ฒฝํ๊ฒ ๋ค์์คํ์ด์คํํ๋ค๊ณ ๋ฏฟ๋์? ์ด๋ฌํ ๊ณต์์ ์ธ ์์กด์ฑ ๋ชจ๋ธ์ ๋ถ์ฌ๋ ์ข ์ข ๋ชจ๋ ๊ฒ์ ํ๋์ ๊ฑฐ๋ํ CSS ํ์ผ๋ก ๋ฒ๋ค๋งํ๊ฒ ๋ง๋ค์ด, ์คํ์ผ์ด ์ด๋์ ์ค๋์ง์ ๋ํ ๋ช ํ์ฑ์ ์๊ณ ์ ์ง๋ณด์์ ์ ๋ชฝ์ ๋ง๋ญ๋๋ค.
๊ธฐ์กด ํด๊ฒฐ์ฑ ์ ํ๊ณ
๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ๋ ์ด๋ฌํ ํ๊ณ๋ฅผ ์ฐํํ๊ธฐ ์ํ ํด๊ฒฐ์ฑ ์ ๋ง๋๋ ๋ฐ ๋งค์ฐ ํ์ ์ ์ด์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ๊ฐ์ ๊ณ ์ ํ ๋จ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค:
- ๋ฐฉ๋ฒ๋ก (BEM ๋ฑ): ๋ธ๋ก, ์์, ์์์ด(Block, Element, Modifier) ๋ฐฉ๋ฒ๋ก ์ ๋ค์์คํ์ด์ค๋ฅผ ํ๋ด ๋ด๊ธฐ ์ํด ์๊ฒฉํ ๋ค์ด๋ฐ ์ปจ๋ฒค์
(์:
.card__title--primary)์ ๋ง๋ญ๋๋ค. ์ฅ์ : ๋๊ตฌ ์์ด ์์ CSS๋ง์ผ๋ก ๊ฐ๋ฅํฉ๋๋ค. ๋จ์ : ๋งค์ฐ ๊ธธ๊ณ ์ฅํฉํ ํด๋์ค ์ด๋ฆ์ ๋ง๋ค ์ ์์ผ๋ฉฐ, ์ ์ ์ผ๋ก ๊ฐ๋ฐ์์ ๊ท์จ์ ์์กดํ๊ณ , ์ง์ ํ ์บก์ํ๋ฅผ ์ ๊ณตํ์ง ์์ต๋๋ค. ์ด๋ฆ ์ง์ ์ ์ค์๋ ์ฌ์ ํ ์คํ์ผ ์ ์ถ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. - ๋น๋ ํ์ ๋๊ตฌ (CSS ๋ชจ๋ ๋ฑ): ์ด๋ฌํ ๋๊ตฌ๋ ๋น๋ ์์ CSS๋ฅผ ์ฒ๋ฆฌํ์ฌ ๊ณ ์ ํ ํด๋์ค ์ด๋ฆ(์:
.card_title_a8f3e)์ ์๋์ผ๋ก ์์ฑํฉ๋๋ค. ์ฅ์ : ์ง์ ํ ํ์ผ ์์ค์ ์ค์ฝํ ๊ฒฉ๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋จ์ : Webpack์ด๋ Vite์ ๊ฐ์ ํน์ ๋น๋ ํ๊ฒฝ์ด ํ์ํ๋ฉฐ, ์์ฑํ๋ CSS์ ๋ณด์ด๋ HTML ์ฌ์ด์ ์ง์ ์ ์ธ ์ฐ๊ฒฐ์ ๋๊ณ , ๋ค์ดํฐ๋ธ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ์ด ์๋๋๋ค. - CSS-in-JS: Styled Components๋ Emotion๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด JavaScript ์ปดํฌ๋ํธ ํ์ผ ๋ด์์ ์ง์ CSS๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ฅ์ : ๊ฐ๋ ฅํ ์ปดํฌ๋ํธ ์์ค์ ์บก์ํ์ ๋์ ์คํ์ผ๋ง์ ์ ๊ณตํฉ๋๋ค. ๋จ์ : ๋ฐํ์ ์ค๋ฒํค๋๋ฅผ ์ ๋ฐํ ์ ์๊ณ , JavaScript ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ์ํค๋ฉฐ, ์ ํต์ ์ธ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ฅผ ๋ชจํธํ๊ฒ ๋ง๋ค์ด ๋ง์ ํ์๊ฒ ๋ ผ์์ ์ฌ์ง๊ฐ ์์ต๋๋ค.
- Shadow DOM: ์น ์ปดํฌ๋ํธ(Web Components) ์ ํ๊ตฐ์ ์ผ๋ถ์ธ ๋ค์ดํฐ๋ธ ๋ธ๋ผ์ฐ์ ๊ธฐ์ ๋ก, ์์ ํ DOM ๋ฐ ์คํ์ผ ์บก์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ฅ์ : ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ฅ ๊ฐ๋ ฅํ ํํ์ ๊ฒฉ๋ฆฌ์
๋๋ค. ๋จ์ : ์์
ํ๊ธฐ ๋ณต์กํ ์ ์์ผ๋ฉฐ, ์ธ๋ถ์์ ์ปดํฌ๋ํธ ์คํ์ผ์ ์ง์ (ํ
๋ง ์ค์ )ํ๋ ค๋ฉด CSS ์ฌ์ฉ์ ์ ์ ์์ฑ(Custom Properties)์ด๋
::part๋ฅผ ์ฌ์ฉํ๋ ์๋์ ์ธ ์ ๊ทผ ๋ฐฉ์์ด ํ์ํฉ๋๋ค. ์ ์ญ ์ปจํ ์คํธ์์ CSS ์์กด์ฑ์ ๊ด๋ฆฌํ๊ธฐ ์ํ ํด๊ฒฐ์ฑ ์ ์๋๋๋ค.
์ด ๋ชจ๋ ์ ๊ทผ ๋ฐฉ์์ด ์ ํจํ๊ณ ์ ์ฉํ์ง๋ง, ์ด๋ ๋ชจ๋ ์์๋ฐฉํธ์ ๋๋ค. CSS ํจํค์ง ๊ท์น ์ ์์ ์ค์ฝํ, ์์กด์ฑ, ๊ณต๊ฐ API์ ๊ฐ๋ ์ ์ธ์ด์ ์ง์ ๊ตฌ์ถํ์ฌ ๋ฌธ์ ์ ๊ทผ์์ ํด๊ฒฐํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค.
CSS @package ๊ท์น ์๊ฐ: ๋ค์ดํฐ๋ธ ์๋ฃจ์
์ต๊ทผ W3C ์ ์์์ ํ๊ตฌ๋ CSS ํจํค์ง ๊ฐ๋
์ ๋จ์ผ @package at-rule์ ๊ดํ ๊ฒ์ด ์๋๋ผ, ํจํค์ง ์์คํ
์ ๋ง๋ค๊ธฐ ์ํด ํจ๊ป ์๋ํ๋ ์๋ก์ด ๊ธฐ๋ฅ๊ณผ ํฅ์๋ ๊ธฐ๋ฅ๋ค์ ์งํฉ์ ๊ดํ ๊ฒ์
๋๋ค. ํต์ฌ ์์ด๋์ด๋ ์คํ์ผ์ํธ๊ฐ ๋ช
ํํ ๊ฒฝ๊ณ๋ฅผ ์ ์ํ์ฌ ๋ด๋ถ ์คํ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น๊ณต๊ฐ(private)๋ก ๋ง๋ค๊ณ , ๋ค๋ฅธ ์คํ์ผ์ํธ์์ ์ฌ์ฉํ ์ ์๋๋ก ๊ณต๊ฐ API๋ฅผ ๋ช
์์ ์ผ๋ก ๋
ธ์ถ์ํค๋ ๊ฒ์
๋๋ค.
ํต์ฌ ๊ฐ๋ ๊ณผ ๊ตฌ๋ฌธ
์ด ์์คํ
์ ๊ธฐ๋ฐ์ ๋ ๊ฐ์ง ์ฃผ์ at-rule์ธ @export์ ํ๋ํ๋ @import์ ์์ต๋๋ค. ์คํ์ผ์ํธ๋ ์ด๋ฌํ ๊ท์น์ ์ฌ์ฉํจ์ผ๋ก์จ "ํจํค์ง"๊ฐ ๋ฉ๋๋ค.
1. ๊ธฐ๋ณธ์ ์ผ๋ก ๋น๊ณต๊ฐ(Privacy by Default): ์๊ฐ์ ๊ทผ๋ณธ์ ์ธ ์ ํ์ ํจํค์ง(๋ฐฐํฌ์ฉ CSS ํ์ผ) ๋ด์ ๋ชจ๋ ์คํ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ก์ปฌ ๋๋ ๋น๊ณต๊ฐ๋ก ๊ฐ์ฃผ๋๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ค์ ์บก์ํ๋์ด ๋ช ์์ ์ผ๋ก ๋ด๋ณด๋ด์ง(export) ์๋ ํ ์ ์ญ ์ค์ฝํ๋ ๋ค๋ฅธ ํจํค์ง์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
2. @export๋ฅผ ์ด์ฉํ ๊ณต๊ฐ API: ํ
๋ง ์ค์ ๊ณผ ์ํธ ์ด์ฉ์ฑ์ ํ์ฉํ๊ธฐ ์ํด, ํจํค์ง๋ @export at-rule์ ์ฌ์ฉํ์ฌ ๊ณต๊ฐ API๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ ํจํค์ง๊ฐ "์ด๊ฒ์ด ์ธ๋ถ ์ธ๊ณ๊ฐ ๋ณด๊ณ ์ํธ ์์ฉํ ์ ์๋๋ก ํ์ฉ๋ ๋์ ์ผ๋ถ์
๋๋ค"๋ผ๊ณ ๋งํ๋ ๋ฐฉ์์
๋๋ค. ํ์ฌ ์ด ์ ์์ ์ ํ์๊ฐ ์๋ ์์ฐ์ ๋ด๋ณด๋ด๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค.
- CSS ์ฌ์ฉ์ ์ ์ ์์ฑ(Custom Properties): ํ ๋ง ์ค์ ์ ์ํ ์ฃผ์ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
- ํคํ๋ ์ ์ ๋๋ฉ์ด์ (Keyframe Animations): ๊ณตํต ์ ๋๋ฉ์ด์ ์ ๊ณต์ ํ๊ธฐ ์ํจ์ ๋๋ค.
- CSS ๋ ์ด์ด(Layers): ์บ์ค์ผ์ด๋ ์์๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํจ์ ๋๋ค.
- ๊ธฐํ ์ ์ฌ์ ๋ด๋ณด๋ด๊ธฐ: ํฅํ ์ ์์๋ ์นด์ดํฐ, ๊ทธ๋ฆฌ๋ ์ด๋ฆ ๋ฑ์ ๋ด๋ณด๋ด๋ ๊ฒ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
๊ตฌ๋ฌธ์ ๊ฐ๋จํฉ๋๋ค:
/* my-theme.css ๋ด๋ถ */
@export --brand-primary: #0a74d9;
@export --border-radius-default: 5px;
@export standard-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
3. @import๋ฅผ ์ด์ฉํ ํต์ ๋ ์ฌ์ฉ: ์ต์ํ @import ๊ท์น์ด ๊ฐํ๋ฉ๋๋ค. ์ด๊ฒ์ด ํจํค์ง๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋ด๋ณด๋ด์ง API์ ์ ๊ทผํ๋ ๋ฉ์ปค๋์ฆ์ด ๋ฉ๋๋ค. ์ด ์ ์์๋ ์ ํต์ ์ธ @import๊ฐ ์ผ๊ธฐํ ์ ์๋ ์ ์ญ ๋ค์์คํ์ด์ค ์ค์ผ์ ๋ฐฉ์งํ๋ฉด์ ๊ตฌ์กฐํ๋ ๋ฐฉ์์ผ๋ก ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ์๋ก์ด ๊ตฌ๋ฌธ์ด ํฌํจ๋ฉ๋๋ค.
/* app.css ๋ด๋ถ */
@import url("my-theme.css"); /* ํจํค์ง์ ๊ณต๊ฐ API๋ฅผ ๊ฐ์ ธ์ต๋๋ค */
์ผ๋จ ๊ฐ์ ธ์ค๋ฉด, ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ด๋ณด๋ด์ง ์ฌ์ฉ์ ์ ์ ์์ฑ์ ์ฌ์ฉํ์ฌ ์์ฒด ์ปดํฌ๋ํธ์ ์คํ์ผ์ ์ง์ ํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ํ ๋ง ํจํค์ง์ ์ ์๋ ๋์์ธ ์์คํ ๊ณผ์ ์ผ๊ด์ฑ๊ณผ ์ค์๋ฅผ ๋ณด์ฅํฉ๋๋ค.
์ค์ ๊ตฌํ: ์ปดํฌ๋ํธ ํจํค์ง ๋ง๋ค๊ธฐ
์ด๋ก ์ ํ๋ฅญํ์ง๋ง, ์ด๊ฒ์ด ์ค์ ๋ก ์ด๋ป๊ฒ ์๋ํ๋์ง ๋ด ์๋ค. ์ฐ๋ฆฌ๋ ์์ฒด ํฌํจ๋๊ณ ํ ๋ง ์ค์ ์ด ๊ฐ๋ฅํ "Alert" ์ปดํฌ๋ํธ ํจํค์ง๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค. ์ด ํจํค์ง๋ ์์ฒด ๋น๊ณต๊ฐ ์คํ์ผ๊ณผ ์ปค์คํฐ๋ง์ด์ง์ ์ํ ๊ณต๊ฐ API๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
1๋จ๊ณ: ํจํค์ง ์ ์ (`alert-component.css`)
๋จผ์ , ์ฐ๋ฆฌ ์ปดํฌ๋ํธ๋ฅผ ์ํ CSS ํ์ผ์ ๋ง๋ญ๋๋ค. ์ด ํ์ผ์ด ์ฐ๋ฆฌ์ "ํจํค์ง"์ ๋๋ค. ์ฐ๋ฆฌ๋ ๊ฒฝ๊ณ (alert)์ ํต์ฌ ๊ตฌ์กฐ์ ๋ชจ์์ ์ ์ํ ๊ฒ์ ๋๋ค. ํน๋ณํ ๋ํผ ๊ท์น์ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ ์ ์ ์ํ์ธ์; ํ์ผ ์์ฒด๊ฐ ํจํค์ง ๊ฒฝ๊ณ์ ๋๋ค.
/* alert-component.css */
/* --- ๊ณต๊ฐ API --- */
/* ์ด ๋ถ๋ถ์ ์ฐ๋ฆฌ ์ปดํฌ๋ํธ์ ์ปค์คํฐ๋ง์ด์ง ๊ฐ๋ฅํ ๋ถ๋ถ์
๋๋ค. */
@export --alert-bg-color: #e6f7ff;
@export --alert-border-color: #91d5ff;
@export --alert-text-color: #0056b3;
@export --alert-border-radius: 4px;
/* --- ๋น๊ณต๊ฐ ์คํ์ผ --- */
/* ์ด ์คํ์ผ์ ์ด ํจํค์ง ๋ด์์ ์บก์ํ๋ฉ๋๋ค.
๊ฐ์ผ๋ก๋ ๋ด๋ณด๋ด์ง ์ฌ์ฉ์ ์ ์ ์์ฑ์ ์ฌ์ฉํฉ๋๋ค.
`.alert` ํด๋์ค๋ ์ด๊ฒ์ด ์ต์ข
์ ์ผ๋ก `@scope`์ ๊ฒฐํฉ๋ ๋ ์ค์ฝํ๊ฐ ์ง์ ๋ฉ๋๋ค. */
.alert {
padding: 1em 1.5em;
border: 1px solid var(--alert-border-color);
background-color: var(--alert-bg-color);
color: var(--alert-text-color);
border-radius: var(--alert-border-radius);
display: flex;
align-items: center;
gap: 0.75em;
}
.alert-icon {
/* ๊ฒฝ๊ณ ๋ด ์์ด์ฝ์ ์ํ ๋ ๋ง์ ๋น๊ณต๊ฐ ์คํ์ผ */
flex-shrink: 0;
}
.alert-message {
/* ๋ฉ์์ง ํ
์คํธ๋ฅผ ์ํ ๋น๊ณต๊ฐ ์คํ์ผ */
flex-grow: 1;
}
ํต์ฌ ์ฌํญ: ๋ช
ํํ ๋ถ๋ฆฌ๊ฐ ์์ต๋๋ค. ์๋จ์ @export ๊ท์น์ ์ธ๋ถ ์ธ๊ณ์์ ๊ณ์ฝ์ ์ ์ํฉ๋๋ค. ์๋์ ํด๋์ค ๊ธฐ๋ฐ ๊ท์น์ ๋ด๋ถ ๊ตฌํ ์ธ๋ถ ์ฌํญ์
๋๋ค. ๋ค๋ฅธ ์คํ์ผ์ํธ๋ .alert-icon์ ์ง์ ํ๊ฒํ
ํ ์ ์์ผ๋ฉฐ ํด์๋ ์ ๋ฉ๋๋ค.
2๋จ๊ณ: ์ ํ๋ฆฌ์ผ์ด์ ์์ ํจํค์ง ์ฌ์ฉํ๊ธฐ (`app.css`)
์ด์ , ๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์๋ก์ด ๊ฒฝ๊ณ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํด ๋ด ์๋ค. ํจํค์ง๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. HTML์ ๊ฐ๋จํ๊ณ ์๋งจํฑํ๊ฒ ์ ์ง๋ฉ๋๋ค.
HTML (`index.html`):
<div class="alert">
<span class="alert-icon">โน๏ธ</span>
<p class="alert-message">์ด๊ฒ์ ์ฐ๋ฆฌ ์ปดํฌ๋ํธ ํจํค์ง๋ฅผ ์ฌ์ฉํ๋ ์ ๋ณด์ฑ ๋ฉ์์ง์
๋๋ค.</p>
</div>
CSS (`app.css`):
/* app.css */
/* 1. ํจํค์ง๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์ด ํ์ผ์ ๊ฐ์ ธ์์
์คํ์ผ์ ์ฒ๋ฆฌํ๊ณ ๋ด๋ณด๋ด์ง ํญ๋ชฉ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ๋ง๋ญ๋๋ค. */
@import url("alert-component.css");
/* 2. ์ ํ๋ฆฌ์ผ์ด์
๋ ์ด์์์ ์ํ ์ ์ญ ์คํ์ผ */
body {
font-family: sans-serif;
padding: 2em;
background-color: #f4f7f6;
}
์ด ์์ ์์ ๊ฒฝ๊ณ ์ปดํฌ๋ํธ๋ ๊ธฐ๋ณธ ํ๋์ ํ
๋ง ์คํ์ผ๋ก ํ์ด์ง์ ๋ ๋๋ง๋ฉ๋๋ค. ์ปดํฌ๋ํธ์ ๋งํฌ์
์ด .alert ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ณ ์คํ์ผ์ํธ๊ฐ ์ํฌํธ๋์๊ธฐ ๋๋ฌธ์ alert-component.css์ ์คํ์ผ์ด ์ ์ฉ๋ฉ๋๋ค.
3๋จ๊ณ: ์ปดํฌ๋ํธ ์ปค์คํฐ๋ง์ด์ง ๋ฐ ํ ๋ง ์ค์
์ง์ ํ ํ์ ๋ณต์กํ ๋ฎ์ด์ฐ๊ธฐ ์์ด ์ปดํฌ๋ํธ์ ํ ๋ง๋ฅผ ์ฝ๊ฒ ์ค์ ํ ์ ์๋ ๋ฅ๋ ฅ์์ ๋์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์คํ์ผ์ํธ์์ ๊ณต๊ฐ API(์ฌ์ฉ์ ์ ์ ์์ฑ)๋ฅผ ๋ฎ์ด์์ผ๋ก์จ "success"์ "danger" ๋ณํ์ ๋ง๋ค์ด ๋ด ์๋ค.
HTML (`index.html`):
<div class="alert">
<p class="alert-message">์ด๊ฒ์ ๊ธฐ๋ณธ ์ ๋ณด์ฑ ๊ฒฝ๊ณ ์
๋๋ค.</p>
</div>
<div class="alert alert-success">
<p class="alert-message">์์
์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!</p>
</div>
<div class="alert alert-danger">
<p class="alert-message">์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ค์ ์๋ํด ์ฃผ์ธ์.</p>
</div>
CSS (`app.css`):
@import url("alert-component.css");
body {
font-family: sans-serif;
padding: 2em;
background-color: #f4f7f6;
}
/* --- ๊ฒฝ๊ณ ์ปดํฌ๋ํธ ํ
๋ง ์ค์ --- */
/* ์ฐ๋ฆฌ๋ .alert-icon๊ณผ ๊ฐ์ ๋ด๋ถ ํด๋์ค๋ฅผ ํ๊ฒํ
ํ์ง ์์ต๋๋ค.
์ค์ง ๊ณต์์ ์ธ ๊ณต๊ฐ API๋ง ์ฌ์ฉํฉ๋๋ค. */
.alert-success {
--alert-bg-color: #f6ffed;
--alert-border-color: #b7eb8f;
--alert-text-color: #389e0d;
}
.alert-danger {
--alert-bg-color: #fff1f0;
--alert-border-color: #ffa39e;
--alert-text-color: #cf1322;
}
์ด๊ฒ์ ์ปดํฌ๋ํธ ์คํ์ผ๋ง์ ๊ด๋ฆฌํ๋ ๊นจ๋ํ๊ณ , ๊ฐ๋ ฅํ๋ฉฐ, ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ๋ฐฉ๋ฒ์
๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋๋ ๊ฒฝ๊ณ ์ปดํฌ๋ํธ์ ๋ด๋ถ ๊ตฌ์กฐ์ ๋ํด ์๋ฌด๊ฒ๋ ์ ํ์๊ฐ ์์ต๋๋ค. ์ค์ง ์์ ์ ์ด๊ณ ๋ฌธ์ํ๋ ์ฌ์ฉ์ ์ ์ ์์ฑ๊ณผ๋ง ์ํธ ์์ฉํฉ๋๋ค. ๋ง์ฝ ์ปดํฌ๋ํธ ์์ฑ์๊ฐ ๋ด๋ถ ํด๋์ค ์ด๋ฆ์ .alert-message์์ .alert__text๋ก ๋ฆฌํฉํ ๋งํ๊ธฐ๋ก ๊ฒฐ์ ํ๋๋ผ๋, ๊ณต๊ฐ ๊ณ์ฝ(์ฌ์ฉ์ ์ ์ ์์ฑ)์ด ๋ณ๊ฒฝ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํ์ผ๋ง์ ๊นจ์ง์ง ์์ ๊ฒ์
๋๋ค.
๊ณ ๊ธ ๊ฐ๋ ๋ฐ ์๋์ง ํจ๊ณผ
CSS ํจํค์ง ๊ฐ๋ ์ ๋ค๋ฅธ ํ๋ CSS ๊ธฐ๋ฅ๋ค๊ณผ ์ํํ๊ฒ ํตํฉ๋์ด ์น ์คํ์ผ๋ง์ ์ํ ๊ฐ๋ ฅํ๊ณ ์์ง๋ ฅ ์๋ ์์คํ ์ ๋ง๋ค๋๋ก ์ค๊ณ๋์์ต๋๋ค.
ํจํค์ง ๊ฐ ์์กด์ฑ ๊ด๋ฆฌ
ํจํค์ง๋ ์ต์ข ์ฌ์ฉ์ ์ ํ๋ฆฌ์ผ์ด์ ๋ง์ ์ํ ๊ฒ์ด ์๋๋๋ค. ์๋ก๋ฅผ ๊ฐ์ ธ์ ์ ๊ตํ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๋์์ธ ํ ํฐ(์์, ๊ธ๊ผด, ๊ฐ๊ฒฉ)๋ง ๋ด๋ณด๋ด๋ ๊ธฐ๋ณธ์ ์ธ "ํ ๋ง" ํจํค์ง๋ฅผ ์์ํด ๋ณด์ธ์.
/* theme.css */
@export --color-brand-primary: #6f42c1;
@export --font-size-base: 16px;
@export --spacing-unit: 8px;
๊ทธ๋ฐ ๋ค์ ๋ฒํผ ์ปดํฌ๋ํธ ํจํค์ง๋ ์ด ํ ๋ง ํจํค์ง๋ฅผ ๊ฐ์ ธ์ ๊ทธ ๊ฐ์ ์ฌ์ฉํ๋ฉด์, ๋์์ ์์ ๋ง์ ๋ ๊ตฌ์ฒด์ ์ธ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ๋ด๋ณด๋ผ ์ ์์ต๋๋ค.
/* button-component.css */
@import url("theme.css"); /* ๋์์ธ ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ */
/* ๋ฒํผ์ ์ํ ๊ณต๊ฐ API */
@export --btn-padding: var(--spacing-unit);
@export --btn-bg-color: var(--color-brand-primary);
/* ๋ฒํผ์ ์ํ ๋น๊ณต๊ฐ ์คํ์ผ */
.button {
background-color: var(--btn-bg-color);
padding: var(--btn-padding);
/* ... ๊ธฐํ ๋ฒํผ ์คํ์ผ */
}
์ด๊ฒ์ ๋ช ํํ ์์กด์ฑ ๊ทธ๋ํ๋ฅผ ๋ง๋ค์ด ์คํ์ผ์ด ์ด๋์ ์ค๋์ง ์ถ์ ํ๊ธฐ ์ฝ๊ฒ ํ๊ณ ์ ์ฒด ๋์์ธ ์์คํ ์ ๊ฑธ์ณ ์ผ๊ด์ฑ์ ๋ณด์ฅํฉ๋๋ค.
CSS ์ค์ฝํ(@scope)์์ ํตํฉ
CSS ํจํค์ง ์ ์์ ๋ ๋ค๋ฅธ ํฅ๋ฏธ๋ก์ด ๊ธฐ๋ฅ์ธ @scope at-rule๊ณผ ๋ฐ์ ํ๊ฒ ๊ด๋ จ๋์ด ์์ต๋๋ค. @scope๋ DOM ํธ๋ฆฌ์ ํน์ ๋ถ๋ถ ๋ด์์๋ง ์คํ์ผ์ ์ ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด ๋์ด ๊ฒฐํฉ๋๋ฉด ์ง์ ํ ์บก์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ํจํค์ง๋ ์ค์ฝํ ๋ธ๋ก ์์ ์คํ์ผ์ ์ ์ํ ์ ์์ต๋๋ค.
/* alert-component.css ๋ด๋ถ */
@scope (.alert) {
:scope {
/* .alert ์์ ์์ฒด๋ฅผ ์ํ ์คํ์ผ */
padding: 1em;
}
.alert-icon {
/* ์ด ์ ํ์๋ .alert ์์ ๋ด๋ถ์ .alert-icon์๋ง ์ผ์นํฉ๋๋ค */
color: blue;
}
}
/* ์ด๊ฒ์ ์ค์ฝํ ๋ฐ์ ์์ผ๋ฏ๋ก ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค */
.alert-icon { ... }
์ด ์กฐํฉ์ ํจํค์ง์ ์คํ์ผ์ด ํต์ ๋ API๋ฅผ ๊ฐ์ง ๋ฟ๋ง ์๋๋ผ, ๋ฌผ๋ฆฌ์ ์ผ๋ก ํ์ด์ง์ ๋ค๋ฅธ ๋ถ๋ถ์ผ๋ก ์ ์ถ๋์ด ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ์ ์ญ ๋ค์์คํ์ด์ค ๋ฌธ์ ๋ฅผ ๊ทผ๋ณธ์ ์ผ๋ก ํด๊ฒฐํฉ๋๋ค.
์น ์ปดํฌ๋ํธ(Web Components)์์ ์๋์ง
Shadow DOM์ด ๊ถ๊ทน์ ์ธ ์บก์ํ๋ฅผ ์ ๊ณตํ์ง๋ง, ๋ง์ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์คํ์ผ๋ง์ ๋ณต์ก์ฑ ๋๋ฌธ์ ์ด๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค. CSS ํจํค์ง ์์คํ
์ ์ด๋ฌํ "๋ผ์ดํธ DOM(light DOM)" ์ปดํฌ๋ํธ๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋์์ ์ ๊ณตํฉ๋๋ค. ์ด๋ Shadow DOM์ผ๋ก์ ์์ ํ ์ ํ ์์ด ์บก์ํ ์ด์ (@scope๋ฅผ ํตํด)๊ณผ ํ
๋ง ์ํคํ
์ฒ(@export๋ฅผ ํตํด)๋ฅผ ์ ๊ณตํฉ๋๋ค. ์น ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํจํค์ง๋ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ํตํด ์ปดํฌ๋ํธ์ Shadow DOM์ผ๋ก ์ ๋ฌ๋๋ ๊ณต์ ๋์์ธ ํ ํฐ์ ๊ด๋ฆฌํ์ฌ ์๋ฒฝํ ํํธ๋์ญ์ ๋ง๋ค ์ ์์ต๋๋ค.
@package์ ๊ธฐ์กด ์๋ฃจ์ ๋น๊ต
์ด ์๋ก์ด ๋ค์ดํฐ๋ธ ์ ๊ทผ ๋ฐฉ์์ ์ค๋๋ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ๊ฒ๋ค๊ณผ ์ด๋ป๊ฒ ๋น๊ต๋ ๊น์?
- vs. CSS ๋ชจ๋: ๋ชฉํ๋ ์ค์ฝํ๊ฐ ์ง์ ๋ ์คํ์ผ์ด๋ผ๋ ์ ์์ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ๊ทธ๋ฌ๋ CSS ํจํค์ง ์์คํ
์ ๋น๋ ๋๊ตฌ ์ปจ๋ฒค์
์ด ์๋ ๋ธ๋ผ์ฐ์ ๋ค์ดํฐ๋ธ ํ์ค์
๋๋ค. ์ด๋ ๋ก์ปฌ ์ค์ฝํ ํด๋์ค ์ด๋ฆ์ ์ป๊ธฐ ์ํด ํน๋ณํ ๋ก๋๋ ๋ณํ์ด ํ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๋ํ ๊ณต๊ฐ API๋ CSS ๋ชจ๋์
:globalํ์ถ๊ตฌ์ ๋น๊ตํ์ฌ@export๋ก ๋ ๋ช ์์ ์ ๋๋ค. - vs. BEM: BEM์ ์ค์ฝํ๋ฅผ ์๋ฎฌ๋ ์ด์ ํ๋ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ๋๋ค. CSS ํจํค์ง ์์คํ ์ ๋ธ๋ผ์ฐ์ ์ ์ํด ๊ฐ์ ๋๋ ์ค์ ์ค์ฝํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ฌด์ธ๊ฐ๋ฅผ ๋ง์ง์ง ๋ง์ ๋ฌ๋ผ๋ ์ ์คํ ์์ฒญ๊ณผ ์ ๊ธด ๋ฌธ์ ์ฐจ์ด์ ๋๋ค. ๋ ๊ฐ๋ ฅํ๊ณ ์ฌ๋์ ์ค์์ ๋ ์ทจ์ฝํฉ๋๋ค.
- vs. Tailwind CSS / ์ ํธ๋ฆฌํฐ ์ฐ์ (Utility-First): Tailwind์ ๊ฐ์ ์ ํธ๋ฆฌํฐ ์ฐ์ ํ๋ ์์ํฌ๋ HTML์์ ์ ์์ค ์ ํธ๋ฆฌํฐ ํด๋์ค๋ก ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐ ์ด์ ์ ๋ง์ถ ์์ ํ ๋ค๋ฅธ ํจ๋ฌ๋ค์์
๋๋ค. CSS ํจํค์ง ์์คํ
์ ๋ ๋์ ์์ค์ ์๋งจํฑ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋๋ ๋ฐ ๋ง์ถฐ์ ธ ์์ต๋๋ค. ์ด ๋์ ๊ณต์กดํ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, Tailwind์
@apply์ง์์ด๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ ํจํค์ง๋ฅผ ๊ตฌ์ถํ๋ฉด์๋ ํ ๋ง ์ค์ ์ ์ํ ๊นจ๋ํ๊ณ ๋์ ์์ค์ API๋ฅผ ๋ด๋ณด๋ผ ์ ์์ต๋๋ค.
CSS ์ํคํ ์ฒ์ ๋ฏธ๋: ์ด๊ฒ์ด ๊ฐ๋ฐ์์๊ฒ ์๋ฏธํ๋ ๊ฒ
๋ค์ดํฐ๋ธ CSS ํจํค์ง ์์คํ ์ ๋์ ์ ์ฐ๋ฆฌ๊ฐ CSS๋ฅผ ์๊ฐํ๊ณ ์์ฑํ๋ ๋ฐฉ์์ ์์ด ๊ธฐ๋ ๋น์ ์ธ ๋ณํ๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด๋ ์๋ ๊ฐ์ ์ปค๋ฎค๋ํฐ ๋ ธ๋ ฅ๊ณผ ํ์ ์ ์ ์ ์ผ๋ก, ๋ง์นจ๋ด ํ๋ซํผ ์์ฒด์ ๋ด์ฅ๋๋ ๊ฒ์ ๋๋ค.
์ปดํฌ๋ํธ ์ฐ์ ์คํ์ผ๋ง์ผ๋ก์ ์ ํ
์ด ์์คํ ์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ๋ชจ๋ธ์ CSS ์ธ๊ณ์ ์ผ๋ฑ ์๋ฏผ์ผ๋ก ํ๊ณ ํ ํฉ๋๋ค. ๊ฐ๋ฐ์๋ค์ด ์๊ณ , ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, ์ง์ ์ผ๋ก ๋ ๋ฆฝ์ ์ธ UI ์กฐ๊ฐ์ ๋ง๋ค๋๋ก ์ฅ๋ คํ๋ฉฐ, ๊ฐ ์กฐ๊ฐ์ ์์ฒด ๋น๊ณต๊ฐ ์คํ์ผ๊ณผ ์ ์ ์๋ ๊ณต๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๋๋ค. ์ด๋ ๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ , ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ฐ๋ฉฐ, ํ๋ ฅ์ ์ธ ๋์์ธ ์์คํ ์ผ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค.
๋ณต์กํ ๋น๋ ๋๊ตฌ์ ๋ํ ์์กด๋ ๊ฐ์
๋น๋ ๋๊ตฌ๋ ์ถ์(minification) ๋ฐ ๋ ๊ฑฐ์ ๋ธ๋ผ์ฐ์ ์ง์๊ณผ ๊ฐ์ ์์ ์ ํญ์ ํ์์ ์ด๊ฒ ์ง๋ง, ๋ค์ดํฐ๋ธ ํจํค์ง ์์คํ ์ ์ฐ๋ฆฌ ๋น๋ ํ์ดํ๋ผ์ธ์ CSS ๋ถ๋ถ์ ๊ทน์ ์ผ๋ก ๋จ์ํํ ์ ์์ต๋๋ค. ํด๋์ค ์ด๋ฆ ํด์ฑ ๋ฐ ์ค์ฝํ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ปค์คํ ๋ก๋์ ํ๋ฌ๊ทธ์ธ์ ํ์์ฑ์ด ์ฌ๋ผ์ ธ ๋ ๋น ๋ฅธ ๋น๋์ ๋ ๊ฐ๋จํ ๊ตฌ์ฑ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
ํ์ฌ ์ํ ๋ฐ ์ต์ ์ ๋ณด ํ์ธ ๋ฐฉ๋ฒ
@export ๋ฐ ๊ด๋ จ ๊ธฐ๋ฅ์ ํฌํจํ CSS ํจํค์ง ์์คํ
์ ํ์ฌ ์ ์ ๋จ๊ณ๋ผ๋ ์ ์ ๊ธฐ์ตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์์ง ์ด๋ค ์์ ์ ์ธ ๋ธ๋ผ์ฐ์ ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๊ฐ๋
๋ค์ W3C์ CSS ์ํน ๊ทธ๋ฃน(Working Group)์์ ํ๋ฐํ ๋
ผ์๋๊ณ ๋ค๋ฌ์ด์ง๊ณ ์์ต๋๋ค. ์ด๋ ์ฌ๊ธฐ์ ์ค๋ช
๋ ๊ตฌ๋ฌธ๊ณผ ๋์์ด ์ต์ข
๊ตฌํ ์ ์ ๋ณ๊ฒฝ๋ ์ ์์์ ์๋ฏธํฉ๋๋ค.
์งํ ์ํฉ์ ํ์ธํ๋ ค๋ฉด:
- ๊ณต์ ์ค๋ช ์ ์ฝ๊ธฐ: CSSWG๋ GitHub์์ ์ ์์ ํธ์คํ ํฉ๋๋ค. "CSS Scope" ๋ฐ ๊ด๋ จ ์ฐ๊ฒฐ/๊ฐ์ ธ์ค๊ธฐ ๊ธฐ๋ฅ์ ๋ํ ์ค๋ช ์๋ฅผ ์ฐพ์๋ณด์ธ์.
- ๋ธ๋ผ์ฐ์ ๋ฒค๋ ํ๋ก์ฐํ๊ธฐ: Chrome ํ๋ซํผ ์ํ, Firefox์ ํ์ค ์ ์ฅ, WebKit์ ๊ธฐ๋ฅ ์ํ ํ์ด์ง์ ๊ฐ์ ํ๋ซํผ์ ์ฃผ์ํ์ธ์.
- ์ด๊ธฐ ๊ตฌํ ์คํํ๊ธฐ: ์ด ๊ธฐ๋ฅ๋ค์ด Chrome Canary๋ Firefox Nightly์ ๊ฐ์ ๋ธ๋ผ์ฐ์ ์ ์คํ์ ํ๋๊ทธ ๋ค์ ํ์ฌ๋๋ฉด, ์ง์ ์ฌ์ฉํด๋ณด๊ณ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ธ์.
๊ฒฐ๋ก : CSS์ ์๋ก์ด ์ฅ
์ ์๋ CSS ํจํค์ง ์์คํ ์ ๋จ์ํ ์๋ก์ด at-rule ์ธํธ ์ด์์ ๋๋ค. ์ด๋ ํ๋์ ์ธ ์ปดํฌ๋ํธ ์ค์ฌ ์น์ ์ํ CSS์ ๊ทผ๋ณธ์ ์ธ ์ฌํด์์ ๋๋ค. ์๋ ๊ฐ์ ์ปค๋ฎค๋ํฐ ์ฃผ๋ ์๋ฃจ์ ์์ ์ป์ ๊ฐ์ง ๊ตํ์ ๊ฐ์ ธ์ ๋ธ๋ผ์ฐ์ ์ ์ง์ ํตํฉํ์ฌ, CSS๊ฐ ์์ฐ์ค๋ฝ๊ฒ ์ค์ฝํ๊ฐ ์ง์ ๋๊ณ , ์์กด์ฑ์ด ๋ช ์์ ์ผ๋ก ๊ด๋ฆฌ๋๋ฉฐ, ํ ๋ง ์ค์ ์ด ๊นจ๋ํ๊ณ ํ์คํ๋ ํ๋ก์ธ์ค๊ฐ ๋๋ ๋ฏธ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
์บก์ํ๋ฅผ ์ํ ๋ค์ดํฐ๋ธ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๊ณ ๋ช ํํ ๊ณต๊ฐ API๋ฅผ ์์ฑํจ์ผ๋ก์จ, ์ด ์งํ๋ ์ฐ๋ฆฌ์ ์คํ์ผ์ํธ๋ฅผ ๋ ๊ฐ๋ ฅํ๊ฒ, ๋์์ธ ์์คํ ์ ๋ ํ์ฅ ๊ฐ๋ฅํ๊ฒ, ๊ทธ๋ฆฌ๊ณ ๊ฐ๋ฐ์๋ก์์ ์ฐ๋ฆฌ์ ์ถ์ ํจ์ฌ ๋ ์ฝ๊ฒ ๋ง๋ค์ด ์ค ๊ฒ์ ์ฝ์ํฉ๋๋ค. ์ ์์์ ๋ณดํธ์ ์ธ ๋ธ๋ผ์ฐ์ ์ง์๊น์ง์ ๊ธธ์ ๋ฉ์ง๋ง, ๊ทธ ๋ชฉ์ ์ง๋ ๋ฏธ๋ ์น์ ๋์ ์ ์ง์ ์ผ๋ก ๋๋นํ ์ ์๋ ๋ ๊ฐ๋ ฅํ๊ณ , ์์ธก ๊ฐ๋ฅํ๋ฉฐ, ์ฐ์ํ CSS์ ๋๋ค.